package com.aigao.golf.common.base

import com.aigao.golf.common.StringEscapeEditor
import com.aigao.golf.common.datatable.DataTablePage
import com.aigao.golf.common.file.fastDFS.pool.ConnectionPool
import com.aigao.golf.common.file.service.ext
import com.aigao.golf.common.result.ResultTo
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.propertyeditors.CustomDateEditor
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.ServletRequestDataBinder
import org.springframework.web.bind.annotation.InitBinder
import org.springframework.web.multipart.MultipartFile
import tk.mybatis.mapper.entity.Example
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.ParameterizedType
import java.text.SimpleDateFormat
import java.util.*

open class BaseController<T : BaseModel<String>>{


    @Autowired
    lateinit var pool : ConnectionPool


    @Autowired
    protected lateinit var adaptService: MyBaseService<T>

    protected val log by lazy {LoggerFactory.getLogger(this::class.java) }

    /**
     * 日期转化与防止XSS攻击
     */
    @InitBinder fun initBinder(binder: ServletRequestDataBinder) {

        binder.registerCustomEditor(Date::class.java,CustomDateEditor(SimpleDateFormat("yyyy-MM-dd HH:mm:ss"),true))

        binder.registerCustomEditor(String::class.java,StringEscapeEditor(false,false,false))
    }

    /**
     * info
     */
    fun l(str : String){
        log.info(str)
    }

    /**
     * debug
     */
    fun d(str: String) {
        log.debug(str)
    }

    /**
     * warning
     */
    fun w(str: String) {
        log.warn(str)
    }

    /**
     * error
     */
    fun e(str: String) {
        log.error(str)
    }

    /**
     * 分页查询
     */
    fun dataTablePage():DataTablePage?{
        getEntryClass()?.let {
            return DataTablePage(adaptService, it)
        }
        return null
    }

    /**
     * 分页查询
     */
    fun dataPage(): ResultTo? {
        dataTablePage()?.let {
            return it.pageList()
        }
        return null
    }


    /**
     * 分页查询
     */
    fun dataPage(parameterMap: Map<String, Any>): ResultTo? {
        dataTablePage()?.let {
            return it.pageList(parameterMap)
        }
        return null
    }


    /**
     * 分页查询
     */
    fun dataPage(example: Example): ResultTo? {
        dataTablePage()?.let {
            return it.pageList(example)
        }
        return null
    }


    /**
     * 分页查询
     */
    fun dataPage(methodName: String): ResultTo? {
        dataTablePage()?.let {
            return it.pageList(methodName)
        }
        return null
    }


    /**
     * 分页查询
     */
    fun dataPage(methodName: String, parameterMap: Map<String, Any>): ResultTo? {
        dataTablePage()?.let {
            return it.pageList(methodName, parameterMap)
        }
        return null
    }


    /**
     * 分页查询
     */
    fun dataPage(baseService: MyBaseService<*>, clazz: Class<*>, methodName: String): ResultTo? {
        try {
            return DataTablePage(baseService, clazz).pageList(methodName)
        } catch (e: InvocationTargetException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        }
        return null
    }


    /**
     * controller 的泛型类
     */
    private fun getEntryClass(): Class<T>? {
        var entityClass: Class<T>? = null
        val genericSuperclass = this::class.java.genericSuperclass
        if (genericSuperclass is ParameterizedType) {
            val types = genericSuperclass.actualTypeArguments
            entityClass = types[0] as Class<T>
        }
        return entityClass
    }


    /**
     * 分页
     */
    fun dataPage(baseService: MyBaseService<*>, clazz: Class<*>, methodName: String, parameterMap: Map<String, Any>): ResultTo? {
        try {
            return DataTablePage(baseService, clazz).pageList(methodName, parameterMap)
        } catch (e: InvocationTargetException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        }
        return null
    }





    /**
     * 从连接池获取storageClient1 用来上传
     */
    fun up(groupName: String, file: MultipartFile): String? {
        val sc1 = pool.checkout(10)
        try {
            return sc1.upload_file1(groupName, file.bytes, file.ext(), null)
        } catch (e: Exception) {
            pool.drop(sc1)
            e.printStackTrace()
        }
        return null
    }


    /**
     * 下载
     */
    fun dwn(storageId: String?,fileName : String): ResponseEntity<ByteArray>? {
        val sc1 = pool.checkout(10)
        return try {
            ResponseEntity(sc1.download_file1(storageId),buildDownHeaders(fileName), HttpStatus.CREATED)
        }catch (e:Exception){
            pool.drop(sc1)
            e.printStackTrace()
            null
        }
    }


    /**
     * 文件删除
     */
    fun del(storageId: String?): Boolean {
        val sc1 = pool.checkout(10)
        sc1.delete_file1(storageId)
        return true
    }



    private fun buildDownHeaders(fileName: String): HttpHeaders {
        val headers = HttpHeaders()
        headers.setContentDispositionFormData("attachment", String(fileName.toByteArray(Charsets.UTF_8), Charsets.ISO_8859_1))
        headers.contentType = MediaType.APPLICATION_OCTET_STREAM
        return headers
    }



    companion object {
        val GROUP1 = "group1"
    }

}
